package client;

import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;
import java.util.Random;

/**
 * @author Rob
 *
 */
public class SortClient {

	public static void main(String[] args) {
		SortClient sc = new SortClient();
		sc.sort();
	}

	/**
	 * Create numbers to sort. Create ListJoiner to observe the threads that are made.
	 */
	@SuppressWarnings("rawtypes")
	public void sort() {
		//some values to easy replace for testing
		int amountOfNumbers = 10000;
		int sortParts = 3;
		//make stuff
		Comparable[] sortTheseNumbers = this.generateRandomList(amountOfNumbers, Integer.class);
		Comparable[][] lists = spliceTheList(sortTheseNumbers, sortParts);
		ListJoiner lj = new ListJoiner(sortParts);
		int volgNummer = 0;
		//sort the lists in threads
		for(Comparable[] lst : lists) {
			SorterThread st = new SorterThread(lst, volgNummer, lj);
			st.sort();
			volgNummer++;
		}
	}

	/**
	 * Generate random numbers
	 * @param length	the amount of numbers to generate
	 * @return randomIntegers	The list of numbers
	 */
	private Comparable[] generateRandomIntegers(int length) {
		Comparable[] randomIntegers = new Comparable[length];
		Random random = new Random();
		for(int i = 0; i<randomIntegers.length; i++) {
			randomIntegers[i] = (Integer) random.nextInt(10000);
		}
		return randomIntegers;
	}

	/**
	 * Generate random Strings
	 * @param length	length of the list.
	 * @return randomStrings	the list of random strings.
	 */
	@SuppressWarnings("rawtypes")
	private Comparable[] generateRandomStrings(int length) {
		Comparable[] randomStrings = new Comparable[length];
		Random random = new Random();
		for(int i = 0; i<randomStrings.length; i++) {
			String wordString = "";
			int stringLength = 1+random.nextInt(15);
			for(int j = 0; j<stringLength;j++){
				int minAndMaxCharacter = 66+ random.nextInt(25);
				wordString += (char)minAndMaxCharacter;
			}
			randomStrings[i] = wordString;
		}
		return randomStrings;
	}

	/**
	 * Generate random list. THe result can vary between 3 different values in a list.
	 * @param length	length of the list
	 * @param type	The type of list
	 * @return randomComparables	The list of comparables.
	 */
	@SuppressWarnings("rawtypes")
	private Comparable[] generateRandomList(int length, Class type) {
		Comparable[] randomComparables = new Comparable[length];
		if(type.getName().equals("java.lang.Integer")) {
			randomComparables = this.generateRandomIntegers(length);
		}
		else if(type.getName().equals("java.lang.String")) {
			randomComparables = this.generateRandomStrings(length);
		}
		else if(type.getName().equals("client.Wallet")) {
			randomComparables = this.generateRandomWallets(length);
		}
		return randomComparables;
	}

	/**
	 * Generate random wallets
	 * @param length	length of the list
	 * @return randomWallets	The list of random wallets.
	 */
	@SuppressWarnings("rawtypes")
	private Comparable[] generateRandomWallets(int length) {
		Comparable[] randomWallets = new Comparable[length];
		for(int i=0;i<length;i++) {
			randomWallets[i] = new Wallet();
		}
		return randomWallets;
	}

	/**
	 * Splice the list into x amount of lists. Then return the list.
	 * @param spliceThisList	The list that needs to be spliced.
	 * @param sorterAmount	the amount of lists to splice it in.
	 * @return	splicedLists	A list filled with spliced lists
	 */
	public Comparable[][] spliceTheList(Comparable[] spliceThisList, int sorterAmount) {
		Comparable[][] splicedLists = new Comparable[sorterAmount][];
		ArrayList<Comparable>[] tempHelp = new ArrayList[sorterAmount];
		int biggestNr = (Integer) spliceThisList[0];
		int smallestNr = biggestNr;
		for(int o = 0; o<spliceThisList.length;o++ ) {
			if(biggestNr < (Integer) spliceThisList[o]) {
				biggestNr = (Integer) spliceThisList[o];
			}
			if(smallestNr > (Integer) spliceThisList[o]) {
				smallestNr = (Integer) spliceThisList[o];
			}
		}
		int max = ((biggestNr/sorterAmount)+1)+smallestNr;
		int increment = max;
		for(int j = 0; j<sorterAmount;j++){
			tempHelp[j] = new ArrayList<Comparable>(); 
			int positionInList = 0;
			for(int i = 0; i<spliceThisList.length; i++) {
				if((spliceThisList[i].compareTo(smallestNr-1) == 1 )&& spliceThisList[i].compareTo(max) == -1) {
					tempHelp[j].add(spliceThisList[i]);
					positionInList++;
				}
			}
			splicedLists[j] = (Comparable[]) tempHelp[j].toArray(new Comparable[tempHelp[j].size()]);
			smallestNr = max;
			max += increment;
		}
		return splicedLists;
	}
}
